﻿using HtmlAgilityPack;
using log4net;
using log4net.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;


namespace LogoCrawler
{
    class Program
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {

            var configFile = Directory.GetCurrentDirectory() + @"\log4net.config";
            XmlConfigurator.Configure(new FileInfo(configFile));

            log.Info("Logo Stealer started...");

            Dictionary<string, string> CategoriesUrls = new Dictionary<string, string>();

            string baseUrl = "http://www.brandprofiles.com";
            string Url = "http://www.brandprofiles.com/logos";
            string pageNumber = "?p={0}";
            int currentPage = 2;

            HtmlWeb web = new HtmlWeb();
            HtmlDocument doc = web.Load(Url);

            var categories = doc.DocumentNode.SelectNodes(@"//*[@id=""cat-list""]/li/div/a");

            foreach (var category in categories)
            {
                string categoryName = category.InnerHtml;
                string categoryUrl = category.Attributes["href"].Value;
                CategoriesUrls.Add(categoryName, baseUrl + categoryUrl);
            }

            foreach (var categoryUrl in CategoriesUrls)
            {
                HtmlNodeCollection linksToDetails = null;
                try
                {
                    doc = web.Load(categoryUrl.Value);
                    linksToDetails = doc.DocumentNode.SelectNodes(@"//*[@id=""cat-logos""]/li/a");
                }
                catch (Exception ex)
                {

                    log.Error(string.Format("Error occured {0}.", ex.Message));
                }

                while (linksToDetails != null)
                {
                    Parallel.ForEach(linksToDetails, (link, state, i) =>
                    {
                        try
                        {
                            doc = web.Load(baseUrl + link.Attributes["href"].Value);
                            var img = doc.DocumentNode.SelectSingleNode(@"//*[@id=""logo-img""]/img");
                            DownloadImage(categoryUrl.Key, img.Attributes["src"].Value);
                        }
                        catch (Exception ex)
                        {

                            log.Error(string.Format("Error occured {0}.", ex.Message));
                        }

                    });
                    try
                    {
                        doc = web.Load(categoryUrl.Value + string.Format(pageNumber, currentPage));
                        linksToDetails = doc.DocumentNode.SelectNodes(@"//*[@id=""cat-logos""]/li/a");
                    }
                    catch (Exception ex)
                    {

                        log.Error(string.Format("Error occured {0}.", ex.Message));
                    }

                    currentPage++;
                    log.Debug(string.Format("{0} on page {1}", categoryUrl.Key, currentPage - 1));
                }
                currentPage = 2;
            }
            log.Info("Logo Stealer finished.");
        }

        public static async void DownloadImage(string category, string url)
        {
            try
            {
                HttpClient client = new HttpClient();
                FileInfo fi = new FileInfo(new Uri(url).LocalPath);
                string destinationPath = Path.Combine(category, fi.Name);
                Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
                HttpResponseMessage response = await client.GetAsync(url);
                response.EnsureSuccessStatusCode();

                using (FileStream fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                {
                    await response.Content.CopyToAsync(fileStream);
                }
                log.Info(string.Format("file {0} saved.", destinationPath));
            }
            catch (Exception ex)
            {

                log.Error(string.Format("Error occured {0}.", ex.Message));
            }

        }
    }
}
